﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.IO;

using HtmlAgilityPack;

namespace TorBrowserUpdater
{
    class Tools
    {
        public static HtmlDocument DownloadHtmlDocument(string url)
        {
            var htmlString = DownloadString(url);
            var doc = new HtmlDocument();
            doc.LoadHtml(htmlString);

            return doc;
        }

        public static string DownloadString(string url)
        {
            string outputFilepath = Path.GetTempFileName();
            DownloadFile(url, outputFilepath);
            var contentString = File.ReadAllText(outputFilepath);
            File.Delete(outputFilepath);

            return contentString;
        }

        public static void DownloadFile(string url, string destination)
        {
            string arguments = "-O \"" + destination + "\""
                                + " --no-check-certificate"
                                + ' ' + url;

            try
            {
                StartProgram("wget", arguments);
            }
            catch(Win32Exception ex)
            {
                if(ex.NativeErrorCode == 2)
                {
                    throw new Exception(
                        "Could not check for new version of Tor Browser Bundle : wget is not accessible"
                            + " (not in the same folder and/or not registered in Path).",
                        ex);
                }

                throw;
            }
        }

        public static void StartProgram(string command)
        {
            StartProgram(command, null);
        }

        public static void StartProgram(string command, string arguments)
        {
            StartProgram(command, arguments, null);
        }

        public static void StartProgram(string command, string arguments, string workingDirectory)
        {
            var proc = new Process
                {
                    StartInfo = new ProcessStartInfo
                        {
                            FileName = command,
                            UseShellExecute = false
                        }
                };
            if (!string.IsNullOrEmpty(workingDirectory))
                proc.StartInfo.WorkingDirectory = workingDirectory;

            if (arguments != null)
                proc.StartInfo.Arguments = arguments;

            proc.Start();
            proc.WaitForExit();
        }

        public static Stream ToStream(string text, Encoding encoding = null)
        {
            if(encoding == null)
            {
                encoding = Encoding.ASCII;
            }
            return new MemoryStream(encoding.GetBytes(text), false);
        }

        /// <summary>
        /// Check if <paramref name="filePath"/> exists on disk.  
        /// If it does, returns the path of the file, else throws an exception with <paramref name="errorMessage"/> as message.
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="errorMessage"> </param>
        /// <returns></returns>
        public static string EnsureFileExists(string filePath, string errorMessage)
        {
            if(!File.Exists(filePath))
            {
                throw new TBBUpdaterException(errorMessage);
            }
            return filePath;
        }
    }
}
